package Raid;

import java.io.IOException;
import org.lwjgl.LWJGLException;
import org.lwjgl.Sys;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.newdawn.slick.geom.*;
import org.newdawn.slick.Image;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;
import org.newdawn.slick.util.ResourceLoader;


public class Raid {

	static final int windowWidth = 800;
	static final int windowHeight = 640;
	double shoot = 0;
	
	static int screenIndex = 1;  // 0 = menu, 1 = game
	
	/** time at last frame */
	long lastFrame;
	/** frames per second */
	int fps;
	/** last fps time */
	long lastFPS;
	
	Palo palo;
	Squirm s;
	
	
	Environment env;
	Image hMap;
	
	Texture paloTex;
		
	
	public void start() {
		try {
			Display.setDisplayMode(new DisplayMode(windowWidth, windowHeight));
			Display.create();
		} catch (LWJGLException e) {
			e.printStackTrace();
			System.exit(0);
		}
		loadPaloTextures();
		loadGrassTextures();
		loadHeightMap();
		loadLaserTextures();
		loadSquirmTextures();
		env = new Environment(windowWidth, windowHeight, 50, 40, hMap);
		palo = new Palo(env, 720, 10);
		palo.texture = paloTex;
		initGL(); // init OpenGL
		getDelta(); // call once before loop to initialise lastFrame
		lastFPS = getTime(); // call before loop to initialise fps timer
 
		while (!Display.isCloseRequested()) {
			int delta = getDelta();
 
			update(delta);
			renderGL();
 
			Display.update();
			Display.sync(100); // cap fps to 60fps
		}
 
		Display.destroy();
	}
	
	
	/** 
	 * Calculate how many milliseconds have passed 
	 * since last frame.
	 * 
	 * @return milliseconds passed since last frame 
	 */
	public int getDelta() {
	    long time = getTime();
	    int delta = (int) (time - lastFrame);
	    lastFrame = time;
 
	    return delta;
	}
 
	/**
	 * Get the accurate system time
	 * 
	 * @return The system time in milliseconds
	 */
	public long getTime() {
	    return (Sys.getTime() * 1000) / Sys.getTimerResolution();
	}
 
	/**
	 * Calculate the FPS and set it in the title bar
	 */
	public void updateFPS() {
		if (getTime() - lastFPS > 1000) {
			Display.setTitle("FPS: " + fps);
			fps = 0;
			lastFPS += 1000;
		}
		fps++;
	}
	
	
	
	public void initGL() {
		GL11.glMatrixMode(GL11.GL_PROJECTION);
		GL11.glEnable(GL11.GL_DEPTH_TEST);
		GL11.glEnable(GL11.GL_BLEND);
		GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
		//GL11.glEnable(GL11.GL_LIGHTING);
		
		GL11.glLoadIdentity();
		GL11.glOrtho(0, windowWidth, windowHeight, 0, 30, -30);
		GL11.glMatrixMode(GL11.GL_MODELVIEW);
		GL11.glEnable(GL11.GL_TEXTURE_2D);  
	}
	
	
	public void renderGL() {
		// Clear The Screen And The Depth Buffer
		GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
		// R,G,B,A Set The Color To Blue One Time Only
		//GL11.glColor3f(0.5f, 0.5f, 1.0f);
		GL11.glPushMatrix();
			GL11.glColor3d(1.0, 1.0, 1.0);  // THIS IS REALLY NOT NEEDED USUALLY
			palo.render();
			env.render();
		GL11.glPopMatrix();
	}
 
	
	public void update(int delta) {
		shoot -= ((double)delta)/100;
		pollInput(); 
		if (screenIndex == 1){
			palo.doLogic(delta);
			env.tick(delta);
		}
		updateFPS(); // update FPS Counter
	}
	
	
	public void pollInput() { 
        if (Mouse.isButtonDown(0) && shoot <= 0) {
        	//int x = Mouse.getX();
        	//int y = Mouse.getY();
        	palo.shootLaser(Mouse.getX(),windowHeight-Mouse.getY());
        	//System.out.println("MOUSE DOWN @ X: " + x + " Y: " + y);
        	shoot = 1.0;
        }
        else if (!Mouse.isButtonDown(0)){
        	shoot = 0.0;
        }
 
        while (Keyboard.next()) {
        	if (Keyboard.getEventKeyState()) {
        		if (Keyboard.getEventKey() == Keyboard.KEY_SPACE) {
        			//palo.jump(true); 
        		} else if (Keyboard.getEventKey() == Keyboard.KEY_A) {
        			palo.walkLeft(-1);
        			palo.facing = -1;
        			palo.lastFacing = -1;
        		} else if (Keyboard.getEventKey() == Keyboard.KEY_D) {
        			palo.walkRight(1);
        			palo.facing = 1;
        			palo.lastFacing = 1;
        		} else if (Keyboard.getEventKey() == Keyboard.KEY_W){
        			palo.jump(true);
        			
        			//palo.lookingUp = true;
        		} //else if (Keyboard.getEventKey() == Keyboard.KEY_C){
        		//	palo.shootLaser(Mouse.getX(),Mouse.getY());
        		//}
        	} else {
        		if (Keyboard.getEventKey() == Keyboard.KEY_SPACE) {
        			//palo.jump(false);
        		} else if (Keyboard.getEventKey() == Keyboard.KEY_A) {
        			palo.walkLeft(0);
        		} else if (Keyboard.getEventKey() == Keyboard.KEY_D) {
        			palo.walkRight(0);
        		} else if (Keyboard.getEventKey() == Keyboard.KEY_W){
        			palo.jump(false);
        			
        			//palo.lookingUp = false;
        		} 
        	}
        }
    }
	
	
	public void loadGrassTextures(){			 
		try {
			Grass.textures = new Texture[Grass.texNames.length];
			for (int i = 0; i < Grass.texNames.length; i++){
				Grass.textures[i] = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream(Grass.texNames[i]));
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
		
	public void loadHeightMap(){
		try {
			// load texture from PNG file
			hMap = new Image(TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream("res/heightMap.png")));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public void loadPaloTextures(){
		try {
			// load texture from PNG file
			paloTex = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream("res/palo.png"));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public void loadLaserTextures(){
		try {
			// load texture from PNG file
			Laser.texture = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream("res/laser.png"));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public void loadSquirmTextures(){
		try {
			// load texture from PNG file
			Squirm.textures = new Texture[Squirm.texNames.length];
			for (int i = 0; i < Squirm.texNames.length; i++){
				Squirm.textures[i] = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream(Squirm.texNames[i]));
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	
	public static void main(String[] argv) {
		Raid game = new Raid();
		game.start();
	}
	
}
